package com.icesoft.base.admin.service;

import com.icesoft.base.admin.entity.SysUser;
import com.icesoft.base.admin.entity.dto.SysUserDTO;
import com.icesoft.base.manager.base.BaseService;
import com.icesoft.base.manager.entity.security.SysRole;
import com.icesoft.base.manager.entity.system.SysOrg;
import com.icesoft.base.manager.service.security.SysRoleService;
import com.icesoft.base.manager.service.system.SysOrgService;
import com.icesoft.core.common.exception.CheckException;
import com.icesoft.core.dao.criteria.QueryBuilder;
import lombok.AllArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.session.FindByIndexNameSessionRepository;
import org.springframework.session.Session;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Service
@AllArgsConstructor
public class SysUserService extends BaseService<SysUser> {
    private final PasswordEncoder passwordEncoder;
    private final SysRoleService sysRoleService;
    private final SysOrgService orgService;
    private final FindByIndexNameSessionRepository<? extends Session> sessionRepository;

    public int forceLogout(int userId) {
        SysUser sysUser = load(userId);
        Map<String, ? extends Session> map = sessionRepository.findByPrincipalName(sysUser.getUsername());
        int size = 0;
        for (String sessionId : map.keySet()) {
            size++;
            sessionRepository.deleteById(sessionId);
        }
        return size;
    }

    public SysUserDTO convertUser(SysUser sysUser) {
        SysUserDTO sysUserDTO = new SysUserDTO(sysUser);
        List<SysRole> sysRoles = sysRoleService.findByUserId(sysUser.getId());
        List<String> roleNames = new ArrayList<>();
        List<Integer> roleIds = new ArrayList<>();
        if (!sysRoles.isEmpty()) {
            for (SysRole sysRole : sysRoles) {
                roleIds.add(sysRole.getId());
                roleNames.add(sysRole.getName());
            }
        }
        SysOrg org = orgService.load(sysUser.getOrgId());
        sysUserDTO.setOrgName(org == null ? "-" : org.getName());
        sysUserDTO.setRoleNames(StringUtils.join(roleNames, ','));
        sysUserDTO.setRoleIds(StringUtils.join(roleIds, ','));
        sysUserDTO.setOnlineSize(sessionRepository.findByPrincipalName(sysUser.getUsername()).size());
        return sysUserDTO;
    }

    public boolean checkCompanyCanDelete(int companyId) {
        return isExist(QueryBuilder.get("companyId", companyId));
    }

    public SysUser findByPhone(String phone) {
        if (StringUtils.isBlank(phone)) {
            throw new UsernameNotFoundException("手机号不能为空");
        }
        QueryBuilder qb = QueryBuilder.get("phone", phone).skipFilter();
        return unique(qb);
    }

    public void updatePhone(SysUser sysUser, String newPhone) {
        if (newPhone.equals(sysUser.getPhone())) {
            return;
        }
        if (findByPhone(newPhone) != null) {
            throw new CheckException("手机号已存在");
        }
        sysUser.setPhone(newPhone);
        update(sysUser);
    }

    public SysUser findByUsername(String username) {
        return unique(QueryBuilder.get("username", username).skipFilter());
    }

    public void updatePassword(SysUser sysUser, String newPassword) {
        sysUser.setPassword(passwordEncoder.encode(newPassword));
        sysUser.setPasswordUpdateTime(new Date());
        save(sysUser);
    }

    public boolean checkPassword(SysUser sysUser, String sourcePassword) {
        return passwordEncoder.matches(sourcePassword, sysUser.getPassword());
    }

    public SysUser loadByUserToken(String userToken) {
        return unique(QueryBuilder.get("userToken", userToken));
    }
}
